package com.szbber.commen.service

import android.annotation.SuppressLint
import android.app.Service
import android.content.Intent
import android.net.ConnectivityManager
import android.os.Build
import android.os.IBinder
import android.util.Log
import com.orhanobut.logger.Logger
import com.szbber.commen.base.BaseApplication
import com.szbber.commen.base.BaseEvenBus
import com.szbber.commen.base.Constant
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.util.concurrent.TimeUnit

class MqttService: Service() {

    val TAG: String = MqttService::class.java.simpleName
    private var mqttAndroidClient: MqttAndroidClient? = null
    private var mMqttConnectOptions: MqttConnectOptions? = null
    var HOST = "tcp://122.112.148.38:1883" //服务器地址（协议+地址+端口号）

    var USERNAME = "admin" //用户名

    var PASSWORD = "public" //密码

    var PUBLISH_TOPIC = "/server/device/status" //发布主题

    var RESPONSE_TOPIC = "/server/device/status" //响应主题

    @SuppressLint("MissingPermission",
        "HardwareIds") //    public String CLIENTID = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
    //            ? Build.getSerial() : Build.SERIAL;//客户端ID，一般以客户端唯一标识符表示，这里用设备序列号表示
    var CLIENTID = Build.SERIAL


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        init()
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    /**
     * 发布 （模拟其他客户端发布消息）
     *
     * @param message 消息
     */
    fun publish(message: String) {
        val topic = PUBLISH_TOPIC
        val qos = 1
        val retained = false
        try { //参数分别为：主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
            mqttAndroidClient?.publish(topic, message.toByteArray(), qos, retained)
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }

    /**
     * 响应 （收到其他客户端的消息后，响应给对方告知消息已到达或者消息有问题等）
     *
     * @param message 消息
     */
    fun response(message: String) {
        val topic = RESPONSE_TOPIC
        val qos = 1
        val retained = false
        try { //参数分别为：主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
            mqttAndroidClient?.publish(topic, message.toByteArray(), qos, retained)
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }

    /**
     * 初始化
     */
    private fun init() {

        //        String serverURI = HOST; //服务器地址（协议+地址+端口号）
//        val serverURI: String = PreferUtil.getInstance().getMqtt_host()
        mqttAndroidClient = MqttAndroidClient(this, HOST, CLIENTID)
        mqttAndroidClient?.setCallback(mqttCallback) //设置监听订阅消息的回调
        mMqttConnectOptions = MqttConnectOptions()
        mMqttConnectOptions?.isCleanSession = true //设置是否清除缓存
        mMqttConnectOptions?.connectionTimeout = 100 //设置超时时间，单位：秒
        mMqttConnectOptions?.keepAliveInterval = 100 //设置心跳包发送间隔，单位：秒
        mMqttConnectOptions?.userName = USERNAME //设置用户名
        mMqttConnectOptions?.password = PASSWORD.toCharArray() //设置密码

        // last will message
        var doConnect = true
        val message = "{\"terminal_uid\":\"$CLIENTID\"}"
        val topic = PUBLISH_TOPIC
        val qos = 1
        val retained = false
        if (message != "" || topic != "") {
            try {
                mMqttConnectOptions!!.setWill(topic, message.toByteArray(), qos, retained)
            } catch (e: Exception) {
                Log.i(TAG, "Exception Occured", e)
                doConnect = false
                iMqttActionListener.onFailure(null, e)
            }
        }
        if (doConnect) {
            doClientConnection()
        }
    }

    /**
     * 连接MQTT服务器
     */
    private fun doClientConnection() {
        mqttAndroidClient?.apply {
            if (!isConnected && isConnectIsNomarl()) {
                try {
                  connect(mMqttConnectOptions, null, iMqttActionListener)
                } catch (e: MqttException) {
                    e.printStackTrace()
                }
            }
        }
    }

    /**
     * 判断网络是否连接
     */
    private fun isConnectIsNomarl(): Boolean {
        val connectivityManager =
            this.applicationContext.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        val info = connectivityManager.activeNetworkInfo
        return if (info != null && info.isAvailable) {
            val name = info.typeName
            Log.i(TAG, "当前网络名称：$name")
            true
        } else {
            /*没有可用网络的时候，延迟3秒再尝试重连*/
//           Handler ().postDelayed({ doClientConnection() },
            BaseApplication.MAIN_EXECUTOR.scheduleWithFixedDelay({
                doClientConnection()
            },0,3,TimeUnit.SECONDS)
            Log.i(TAG, "没有可用网络")

            false
        }
    }

    //MQTT是否连接成功的监听
    private val iMqttActionListener: IMqttActionListener = object : IMqttActionListener {
        override fun onSuccess(arg0: IMqttToken) {
            Log.i(TAG, "连接成功 ")
            try {
                mqttAndroidClient?.subscribe(PUBLISH_TOPIC, 1) //订阅主题，参数：主题、服务质量
            } catch (e: MqttException) {
                e.printStackTrace()
            }
        }

        override fun onFailure(arg0: IMqttToken, arg1: Throwable) {
            arg1.printStackTrace()
            Log.i(TAG, "连接失败 ")
            doClientConnection() //连接失败，重连（可关闭服务器进行模拟）
        }
    }

    //订阅主题的回调
    private val mqttCallback: MqttCallback = object : MqttCallback {
        @Throws(Exception::class)
        override fun messageArrived(topic: String, message: MqttMessage) {
            Logger.e("收到消息： "+String(message.payload))
            EventBus.getDefault().post(BaseEvenBus(messageId = Constant.MYMQTTSERVICE_MESSGE, mqttMessage = message))
        }

        override fun deliveryComplete(arg0: IMqttDeliveryToken) {}
        override fun connectionLost(arg0: Throwable) {
            Log.i(TAG, "连接断开 ")
            doClientConnection() //连接断开，重连
        }
    }

    override fun onDestroy() {
        try {
            mqttAndroidClient?.disconnect() //断开连接
        } catch (e: MqttException) {
            e.printStackTrace()
        }
        super.onDestroy()
    }

    @Subscribe
    fun getEvenMessage(baseEvenBus: BaseEvenBus?) {

    }

}